import sys
import pg
import time 
import os
from threading import Thread
import subprocess
import shlex
		
def testuj(command,wejscie,wyjscie):
	czas = 0
	prog_name = shlex.split(command)[0]
	
	f1 = None
	f2 = None
	
	if not wejscie is None:
		command+=" < %s " % wejscie
	if not wyjscie is None:
		command+=" > %s " % wyjscie
	
	command += " 2> /dev/null"
	print command
	print ""
	
	prog = subprocess.Popen( command, shell = True ) 
	
	while(czas<=500):
		time.sleep(0.01)
		if prog.poll() is None:
			czas+=1
		else:
			break;
	
	if (czas>=500):
	 	command = "killall %s" % prog_name.split('/')[-1]
	 	prog.kill()
	 	subprocess.call(shlex.split(command))
		return (-1,czas)
		
	return (prog.returncode,czas)

def just_update(con, solutionID, status):
	command = "UPDATE SOLUTION SET status = '%s' WHERE solutionID = %s;" % (status,solutionID)
	con.query(command)
	
def final_update(con, solutionID, status, czas):
	command = "UPDATE SOLUTION SET status = '%s', time = %lf WHERE solutionID = %s;" % (status, czas/100.0, solutionID)
	con.query(command)

def pobierz_main(con, solutionID):
	command = "SELECT main FROM PROBLEM WHERE problemID = %s;" % problemID
	return con.query(command).getresult()

def get_lowest_solutionID_with_time_null(con):
	command = "SELECT MIN(solutionID) FROM SOLUTION WHERE time IS NULL;"
	return con.query(command).getresult()

def go(con, solutionID, problemID):
	try:
		#tworzenie kodu do kompilacji
		print solutionID
		main = pobierz_main(con, problemID)
		main = str(str(main).decode('string_escape'))[3:-4]
		
		fileObj = open("data/solutions/main.cpp","w")
		fileObj.write("\n\n");
		fileObj.write(main)
		fileObj.close()

		command = "cat data/solutions/includes.cpp data/solutions/%d.cpp data/solutions/main.cpp" % int(solutionID)
		
		(returncode,czas) = testuj(command, None, "data/solutions/current.cpp" )
		status = "GENERATING CODE..."
		if returncode < 0:
			status = "GENERATING CODE TIME LIMIT"
		if returncode > 0:
			status = "GENERATING CODE ERROR"
	
		if returncode != 0:
			final_update(con, solutionID, status, czas)
			return 0
		else:
			just_update(con, solutionID, status)
		
		#kompilacja
		(returncode,czas) = testuj("g++ -O2 data/solutions/current.cpp -o data/solutions/current" , None, None )
		status = "PROGRAM IS RUNNING..."
		if returncode < 0:
			status = "COMPILE TIME LIMIT"
		if returncode > 0:
			status = "COMPILE ERROR"
	
		if returncode != 0:
			final_update(con, solutionID, status, czas)
			return 0
		else:
			just_update(con, solutionID, status)
	
		#uruchomienie programu
		(returncode,czas) = testuj("data/solutions/current", "data/tests/%d.in" % int(problemID), "data/tests/currout ")
		status = "JUDGE IS RUNNING..."
		if returncode < 0:
			status = "TIME LIMIT EXCEEDED"
		if returncode > 0:
			status = "RUNTIME ERROR"
	
		if returncode != 0:
			final_update(con, solutionID, status, czas)
			return 0
		else:
			just_update(con, solutionID, status)
		
		#uruchomienie porownywaczki
		(returncode,czas) = testuj("cmp data/tests/%d.out data/tests/currout " % int(problemID), None, None )
		status = "ACCEPTED"
		if returncode < 0:
			status = "INTERNAL ERROR"
		if returncode > 0:
			status = "WRONG ANSWER"
	
		final_update(con, solutionID, status, czas)
	except:
		final_update(con, solutionID, "SPRAWDZACZKA FAILURE", 0.0)

solutionID = sys.argv[1]
problemID = sys.argv[2]

con = pg.connect(dbname='template_base', host='localhost', user='tadmin', passwd='tadmin')
	
a = int(get_lowest_solutionID_with_time_null(con)[0][0])
while a<int(solutionID):
	print a, solutionID
	time.sleep(1)
	a = int(get_lowest_solutionID_with_time_null(con)[0][0])

if a == int(solutionID):
	#TODO sprawdz czy niczego nie ma w kolejce

	go(con, solutionID, problemID)
	
	


